//
//  TabBarController.m
//  WisdomCommunity
//
//  Created by Yahaong on 16/7/19.
//  Copyright © 2016年 zonten. All rights reserved.
//

#import "TabBarController.h"
#import "NavigationController.h"
#import "TabBar.h"
#import "HomeViewController.h"
#import "SceneViewController.h"
#import "VoiceViewController.h"
#import "CommunityController.h"
#import "SecurityViewController.h"
#import "StartViewController.h"
#import "DeviceViewController.h"
#import "FriendViewController.h"
#import "MQTTCoverTool.h"
#import "MQTTSessionManager.h"
#import "MQTTCoverTool.h"
#import "iflyMSC/iflyMSC.h"
#import "IATConfig.h"
#import "ISRDataHelper.h"
#import "RecordingView.h"
#import "PermissionsUtils.h"
#import "UIView+HUD.h"
#import "ZTDevice.h"
#import "MyNavigationController.h"

static NSString * const  GRAMMARTYPEBNF = @"bnf";
static NSString * const  GRAMMARTYPEABNF = @"abnf";

static NSString * _cloudGrammerid =nil;
@interface TabBarController ()
<
TabBarDeelegate,
IFlySpeechRecognizerDelegate,
RecordingViewDelegate
>
@property (nonatomic, strong) TabBar* mTabBar;
@property (nonatomic, strong)RecordingView* recordingView;
@property (nonatomic, strong) NSString *grammarType; //语法类型
@property (nonatomic, strong) IFlySpeechRecognizer *iFlySpeechRecognizer;
@property (nonatomic, strong) IFlyDataUploader *uploader;//数据上传对象
@property (nonatomic, strong) NSMutableString *curResult;//当前session的结果
@end

@implementation TabBarController


- (void)viewDidLoad {
    [super viewDidLoad];
    [self setupTabBarItemTextAttributes];
    [self setupAllChildController];
    [self setupTabBar];
    self.grammarType = GRAMMARTYPEABNF;
    self.uploader = [[IFlyDataUploader alloc] init];
    [self initRecognizer];
}
- (void)setupAllChildController
{
    [self addOneChildController:[[HomeViewController alloc]init] title:@"智能家居" image:@"tabBar_home" selectedImage:@"tabBar_home_selected"];
    [self addOneChildController:[[SceneViewController alloc]init] title:@"智能场景" image:@"tabBar_scene" selectedImage:@"tabBar_scene_selected"];
    [self addOneChildController:[[SecurityViewController alloc]init] title:@"智能安防" image:@"tabBar_security" selectedImage:@"tabBar_security_selected"];
//    [self addOneChildController:[[CommunityController alloc]init] title:@"智慧社区" image:@"tabbar_community" selectedImage:@"tabbar_community_selected"];
    [self addOneChildController:[[FriendViewController alloc]init] title:@"好友" image:@"tabBar_friend" selectedImage:@"tabBar_friend_selected"];
}

- (void)addOneChildController:(UIViewController *)child title:(nonnull NSString *)title image:(nonnull NSString *)image  selectedImage:(nonnull NSString *)selectedImage
{
    if (!child) {
        return;
    }
    if (title.length != 0) {
       child.tabBarItem.title = title;
    }
    child.tabBarItem.image = [UIImage imageNamed:image];
    child.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    UINavigationController*nav = [[NavigationController alloc]initWithRootViewController:child];
    [self addChildViewController:nav];
}

- (void)setupTabBarItemTextAttributes
{
    UITabBarItem *item = [UITabBarItem appearance];
    NSMutableDictionary *normalAttrs = [NSMutableDictionary dictionary];
    NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];
    normalAttrs[NSForegroundColorAttributeName] = RGBColor(51, 51, 51);
    normalAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];
    selectedAttrs[NSForegroundColorAttributeName] = RGBColor(0, 169, 253);
    [item setTitleTextAttributes:normalAttrs forState:UIControlStateNormal];
    [item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
    
}

- (void)showRecordingView
{
    if (self.recordingView) {
        [self.recordingView removeFromSuperview];
        self.recordingView = nil;
    }
    RecordingView* recordingView = [[RecordingView alloc]init];
    recordingView.delegate = self;
    self.recordingView = recordingView;
    UIWindow *window =  [UIApplication sharedApplication].keyWindow;
    [window addSubview:recordingView];
    [recordingView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];
}

- (void)dismissRecordingView
{
    if (self.recordingView) {
        [self.recordingView removeFromSuperview];
        self.recordingView = nil;
    }
}

- (void)recordingViewClick
{
    [self dismissRecordingView];
    [self stop];
}
#pragma mark - RecordingViewDelegate
-(void)tabBarDidClickVoiceButton:(TabBar *)tabBar
{
    AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    switch (status)
    {
        case AVAuthorizationStatusNotDetermined:
        {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
                if (granted)
                {
                    [self buildGrammer];
                }
                else
                {
                    debugLogInfo(@"用户拒绝");
                }
            }];
        }
            break;
        case AVAuthorizationStatusAuthorized:
        {
            // 已经开启授权，可继续
            [self buildGrammer];
        }
             break;
        case AVAuthorizationStatusDenied:
        {
            UIAlertView* alerView = [[UIAlertView alloc]initWithTitle:@"麦克风权限未开启" message:@"麦克风权限未开启，请进入系统【设置】>【隐私】>【麦克风】中打开开关,开启麦克风功能" delegate:self cancelButtonTitle:@"好" otherButtonTitles:@"设置", nil];
            [alerView show];
        }
            break;
        case AVAuthorizationStatusRestricted:
        {
            [self.view yh_showMsgHUD:@"麦克风设备无法访问"];
        }
            break;
        default:
            break;
    }
}

- (void)setupTabBar
{
    TabBar *tabBar = [[TabBar alloc] init];
    tabBar.tabBardelegate = self;
    self.mTabBar = tabBar;
    [self setValue:tabBar forKey:@"tabBar"];
    UIView *backView = [[UIView alloc] initWithFrame:self.tabBar.bounds];
    backView.backgroundColor = [UIColor whiteColor];
    [self.tabBar insertSubview:backView atIndex:0];
    self.tabBar.opaque = YES;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex NS_DEPRECATED_IOS(2_0, 9_0)
{
    if (buttonIndex == 1)
    {
        [[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    }
  
}
/**
 设置识别参数
 ****/
-(void)initRecognizer
{
    //单例模式，无UI的实例
    if (_iFlySpeechRecognizer == nil) {
        _iFlySpeechRecognizer = [IFlySpeechRecognizer sharedInstance];
    }
    _iFlySpeechRecognizer.delegate = self;
    if (_iFlySpeechRecognizer != nil) {
        IATConfig *instance = [IATConfig sharedInstance];
        //开启候选结果
        [_iFlySpeechRecognizer setParameter:@"1" forKey:@"asr_wbest"];
        //设置引擎类型，cloud 或者 local
        [_iFlySpeechRecognizer setParameter:@ "cloud" forKey:[IFlySpeechConstant ENGINE_TYPE]];
        //设置听写模式
        [_iFlySpeechRecognizer setParameter:@"asr" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
        //设置听写结果格式为json
        [_iFlySpeechRecognizer setParameter:@"json" forKey:[IFlySpeechConstant RESULT_TYPE]];
        //参数意义与IATViewController保持一致，详情可以参照其解释
        [_iFlySpeechRecognizer setParameter:instance.speechTimeout forKey:[IFlySpeechConstant SPEECH_TIMEOUT]];
        [_iFlySpeechRecognizer setParameter:instance.vadEos forKey:[IFlySpeechConstant VAD_EOS]];
        [_iFlySpeechRecognizer setParameter:instance.vadBos forKey:[IFlySpeechConstant VAD_BOS]];
        [_iFlySpeechRecognizer setParameter:instance.sampleRate forKey:[IFlySpeechConstant SAMPLE_RATE]];
        if ([instance.language isEqualToString:[IATConfig chinese]]) {
            [_iFlySpeechRecognizer setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
            [_iFlySpeechRecognizer setParameter:instance.accent forKey:[IFlySpeechConstant ACCENT]];
        }else if ([instance.language isEqualToString:[IATConfig english]]) {
            [_iFlySpeechRecognizer setParameter:instance.language forKey:[IFlySpeechConstant LANGUAGE]];
        }
    }
}

/**
 构建语法
 ****/
-(void) buildGrammer
{
    self.mTabBar.buttonEnable = false;
    NSString *grammarContent = nil;
    //设置字符编码
    [self.iFlySpeechRecognizer setParameter:@"utf-8" forKey:[IFlySpeechConstant TEXT_ENCODING]];
    //设置识别模式
    [self.iFlySpeechRecognizer setParameter:@"asr" forKey:[IFlySpeechConstant IFLY_DOMAIN]];
    NSString *strAllDevice = [kDataManager allDeviceName];
    if (strAllDevice.length == 0)
    {
        self.mTabBar.buttonEnable = true;
        return;
    }
    grammarContent = [NSString stringWithFormat:@"#ABNF 1.0 UTF-8;\nlanguage zh-CN;\nmode voice;\nroot $main;\n$main = ($place1$place2)|($place2$place1);\n$place1 = 打开|关闭|关了;\n$place2 = %@;",strAllDevice];
    debugLogInfo(@"grammarContent = %@",grammarContent);
    //开始构建
    [_iFlySpeechRecognizer buildGrammarCompletionHandler:^(NSString * grammerID, IFlySpeechError *error){
        dispatch_async(dispatch_get_main_queue(), ^{
            if (![error errorCode]) {
                NSLog(@"errorCode=%d",[error errorCode]);
                debugLogInfo(@"上传成功");
            }
            else {
                debugLogInfo(@"上传失败");
            }
            _cloudGrammerid = grammerID;
            //设置grammarid
            [self.iFlySpeechRecognizer setParameter:_cloudGrammerid forKey:[IFlySpeechConstant CLOUD_GRAMMAR]];
            [self starRec];
            
        });
    }grammarType:self.grammarType grammarContent:grammarContent];
}

- (void )starRec{
    //确保语法已经上传
    if (![self isCommitted])
    {
//        debugLogInfo(@"还没有上传语法");
        [self.view yh_showMsgHUD:@"网络错误"];
        self.mTabBar.buttonEnable = true;
        return;
    }
    [self showRecordingView];
    self.curResult = nil;
    //保存录音文件，保存在sdk工作路径中，如未设置工作路径，则默认保存在library/cache下
    [self.iFlySpeechRecognizer setParameter:@"asr.pcm" forKey:[IFlySpeechConstant ASR_AUDIO_PATH]];
    //启动语法识别
    BOOL ret = [self.iFlySpeechRecognizer startListening];
    if (ret) {
    }
    else{
        debugLogInfo(@"启动识别服务失败，请稍后重试");//可能是上次请求未结束
        self.mTabBar.buttonEnable = true;
        [self dismissRecordingView];
    }
}

- (void)stop {
    debugLogInfo(@"%s",__func__);
    [self.iFlySpeechRecognizer stopListening];
//    self.mTabBar.buttonEnable = true;
}


- (void)cancel {
    debugLogInfo(@"%s",__func__);
    [self.iFlySpeechRecognizer cancel];
}


-(BOOL) isCommitted
{
    if (_cloudGrammerid == nil || _cloudGrammerid.length == 0)
    {
        return NO;
    }
    return YES;
}
#pragma mark - IFlySpeechRecognizerDelegate

/**
 * 音量变化回调
 * volume   录音的音量，音量范围0~30
 ****/
- (void) onVolumeChanged: (int)volume
{
    NSString * vol = [NSString stringWithFormat:@"音量：%d",volume];
    debugLogInfo(@"%@",vol);
    if (volume == 0)
    {
       self.recordingView.volumeType = ZTVolumeTypeNone;
    }
    else if (volume < 10 && volume > 0 ) {
        self.recordingView.volumeType = ZTVolumeTypeOne;
    }
    else if (volume < 20 && volume >= 10 ) {
        self.recordingView.volumeType = ZTVolumeTypeTwo;
    }
    else if (volume  >= 20) {
        self.recordingView.volumeType = ZTVolumeTypeThree;
    }

}

/**
 开始识别回调
 ****/
- (void) onBeginOfSpeech
{
    debugLogInfo(@"开始识别");
}

/**
 停止识别回调
 ****/
- (void) onEndOfSpeech
{
    debugLogInfo(@"停止识别");
//    self.mTabBar.buttonEnable = true;
}



/**
 识别结果回调（注：无论是否正确都会回调）
 error.errorCode =
 0     听写正确
 other 听写出错
 ****/
- (void) onError:(IFlySpeechError *) error
{
    NSString *text ;
    if (error.errorCode ==0 ) {
        if (self.curResult.length==0 || [self.curResult hasPrefix:@"nomatch"]) {
            text = @"无匹配结果";
            self.curResult = nil;
            debugLogInfo(@"%@",text);
        }
        else
        {
            text = @"识别成功";
            debugLogInfo(@"%@",text);
            debugLogInfo(@"curResult = %@",self.curResult);
            [self controlDevice:self.curResult];
            self.curResult = nil;
        }
    }
    else
    {
        self.curResult = nil;;
        text = [NSString stringWithFormat:@"发生错误：%d %@",error.errorCode,error.errorDesc];
        debugLogInfo(@"%@",text);
    }
    self.mTabBar.buttonEnable = true;
    [self dismissRecordingView];
}


/**
 识别结果回调
 result 识别结果，NSArray的第一个元素为NSDictionary，
 NSDictionary的key为识别结果，value为置信度
 isLast：表示最后一次
 ****/
- (void)onResults:(NSArray *) results isLast:(BOOL)isLast
{
    NSMutableString *result = [[NSMutableString alloc] init];
    NSMutableString * resultString = [[NSMutableString alloc]init];
    NSDictionary *dic = results[0];
    for (NSString *key in dic) {
        [result appendFormat:@"%@",key];
        NSString * resultFromJson =  [ISRDataHelper stringFromABNFJson:result];
        [resultString appendString:resultFromJson];
    }
    if (isLast) {
        debugLogInfo(@"result is:%@",self.curResult);
    }
    [self.curResult appendString:resultString];
}

/**
 取消识别回调
 ****/
- (void)onCancel
{
    debugLogInfo(@"停止识别");
    self.mTabBar.buttonEnable = true;
}


- (void)controlDev:(ZTDevice *)dev action:(NSString *)action channel:(uint8_t)channel
{
    uint8_t actionData = 0;
    if ([action isEqualToString:@"打开"]) {
        actionData = 1;
    }else if ([action isEqualToString:@"关了"] || [action isEqualToString:@"关闭"]) {
        actionData = 0;
    }
    if (dev.devType == ZTDeviceTypeOneWaySocket
        || dev.devType == ZTDeviceTypeOneWay0Switch
        || dev.devType == ZTDeviceTypeOneWaySwitch
        || dev.devType == ZTDeviceTypeGAS
        || dev.devType == ZTDeviceTypeSmoke
        )
    {
        XAITLV* tlv = [[XAITLV alloc]initWithType:XAI_DATA_TYPE_BIN_BOOL bytes:&actionData length:sizeof(actionData)];
        [kMQTTSessionManager.xai sendCMD:0x01 toApsn:dev.apsn toLuid:dev.luid datas:@[tlv]];
    }
    else if (dev.devType == ZTDeviceTypeTwoWay0Switch
              || dev.devType == ZTDeviceTypeTwoWaySwitch
              || dev.devType == ZTDeviceTypeThreeWay0Switch
              || dev.devType == ZTDeviceTypeThreeWaySwitch
              || dev.devType == ZTDeviceTypeFourWay0Switch
              || dev.devType == ZTDeviceTypeFourWaySwitch
              )
    {
        XAITLV* tlv = [[XAITLV alloc]initWithType:XAI_DATA_TYPE_BIN_BOOL bytes:&actionData length:sizeof(actionData)];
        [kMQTTSessionManager.xai sendCMD:channel toApsn:dev.apsn toLuid:dev.luid datas:@[tlv]];
    }
    else if (dev.devType == ZTDeviceTypeLCCamera)
    {
        if (actionData)
        {
            self.selectedIndex = 0;
            [[NSNotificationCenter defaultCenter]postNotificationName:@"open" object:dev];
        }
    }
}

- (void)controlDevice:(NSString *)result
{
    if (result.length <= 2) {
        return;
    }
    NSInteger ctlstrLength = 2;
    NSString *controlStr = [result substringToIndex:ctlstrLength];
    NSString *devName = nil;
    uint8_t  channel = 0;
    if ([controlStr isEqualToString:@"打开"] ||[controlStr isEqualToString:@"关闭"] ||[controlStr isEqualToString:@"关了"]  ) {
        devName = [result substringFromIndex:ctlstrLength];
        if (devName.length == 0) {
            return;
        }
        for (ZTDevice *dev in kDataManager.deviceListenList) {
            if ([dev.getDeviceName isEqualToString:devName]) {
                [self controlDev:dev action:controlStr channel:channel];
                break;
            }
            NSString *strChannel = [devName substringToIndex:devName.length -1] ;
            if ([dev.getDeviceName isEqualToString:strChannel]) {
                channel = [[devName substringFromIndex:devName.length -1] intValue];
                [self controlDev:dev action:controlStr channel:channel];
            }
        }
        
    } else {
        controlStr = [result substringFromIndex:result.length - ctlstrLength];
        if ([controlStr isEqualToString:@"打开"] ||[controlStr isEqualToString:@"关闭"] ||[controlStr isEqualToString:@"关了"]  ) {
            devName = [result substringToIndex:result.length - ctlstrLength];
            if (devName.length == 0) {
                return;
            }
            for (ZTDevice *dev in kDataManager.deviceListenList) {
                if ([dev.getDeviceName isEqualToString:devName]) {
                    [self controlDev:dev action:controlStr channel:channel];
                    break;
                }
                NSString *strChannel = [devName substringToIndex:devName.length -1] ;
                if ([dev.getDeviceName isEqualToString:strChannel]) {
                    channel = [[devName substringFromIndex:devName.length -1] intValue];
                    [self controlDev:dev action:controlStr channel:channel];
                }
            }
            
        }
    }

}

#pragma mark - getters and setters 

- (NSMutableString *)curResult
{
    if (!_curResult) {
        _curResult = [NSMutableString string];
    }
    return _curResult;
}
@end
